package com.yan.core.factory;

import com.yan.core.annotations.parse.ParseAnnotation;
import com.yan.core.utils.ClassUtils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 工厂类，生产对象（使用反射技术）
 */
public class BeanFactory {

    private static Map<String, Object> springBean = new HashMap<>();  // 一级缓存

    private static Map<String, Object> levelBean = new HashMap<>();  // 二级缓存

    private static Map<String, Object> beanFactory = new HashMap<>();  // 三级缓存

    private static Map<String, Class<?>> serviceClassMap = new HashMap<>();  // 存 service class


    public static Object getBean(String id) {
        return springBean.get(id);
    }

    static {
        //获取指定包下面 所有类
        List<Class<?>> allClass = new ClassUtils().getAllClass("classpath*:com/yan/**/*.class");

        //滤掉不是 Service 注解的
        List<Class<?>> serviceClasses = ParseAnnotation.filterNoService(allClass);
        // 添加到 classMap 中
        for (Class<?> serviceClass : serviceClasses) {
            String beanName = ParseAnnotation.parseBeanName(serviceClass);
            serviceClassMap.put(beanName, serviceClass);
        }
        //开始加载所有 serviceClass
        for (Class<?> serviceClass : serviceClasses) {
            try {
                getIocBean(ParseAnnotation.parseBeanName(serviceClass));
            } catch (Exception e) {
                System.err.println("class加载异常 ： " + serviceClass);
                e.printStackTrace();
            }
        }
    }

    private static Object getIocBean(String beanName) throws Exception {
        Class<?> serviceClass = serviceClassMap.get(beanName);
        if (serviceClass == null) {
            throw new ClassNotFoundException("异常" + beanName);
        }
        Object bean = getCacheBean(beanName);
        if (bean == null) {
            bean = doCreateBean(serviceClass);
        }
        return bean;
    }

    private static Object getCacheBean(String beanName) {
        Object bean = springBean.get(beanName);
        if (bean == null) {
            bean = levelBean.get(beanName);
            if (bean == null) {
                bean = beanFactory.get(beanName);
            }
        }
        return bean;
    }


    private static Object doCreateBean(Class<?> beanClass) throws Exception {
        String beanName = ParseAnnotation.parseBeanName(beanClass);
        //三级缓存 实例化对象
        Object bean = beanClass.newInstance();
        beanFactory.put(beanName, bean);
        //设置化属性
        List<Field> fields = ParseAnnotation.filterNoAutowired(beanClass.getDeclaredFields());
        for (Field field : fields) {
            String filedName = ParseAnnotation.parseFiledName(field);
            Object springBean = getIocBean(filedName);
            field.setAccessible(true);
            field.set(bean, springBean);
        }

        //二级缓存 处理增强功能（代理）
        levelBean.put(beanName, bean);
        beanFactory.remove(beanName);
        //判断这个 beanClass是不是事务
        if (ParseAnnotation.isTransactional(beanClass)) {
            ProxyFactory proxyFactory = (ProxyFactory) getIocBean("proxyFactory");
            Class<?>[] interfaces = beanClass.getInterfaces();
            if (interfaces != null && interfaces.length > 0) {
                bean = proxyFactory.transactionJdk(bean);
            } else {
                bean = proxyFactory.transactionCgLib(bean);
            }
        }
        springBean.put(beanName, bean);
        levelBean.remove(beanName);
        return bean;
    }
}
